use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// 基础实体结构体
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]

pub struct Base {
    /// 雪花ID
    #[serde(rename = "_id")]
    pub id: Option<String>,
    /// 名称
    pub name: Option<String>,
    /// 拓展数据
    #[serde(flatten)]
    pub extensions: HashMap<String, serde_json::Value>,
}

impl Default for Base {
    fn default() -> Self {
        Self {
            id: None,
            name: None,
            extensions: HashMap::new(),
        }
    }
}

/// 实体基础结构体
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
pub struct EntityBase {
    /// 基础字段
    #[serde(flatten)]
    pub base: Base,
    /// 状态
    pub status: i32,
    /// 创建人员ID
    pub create_user: Option<String>,
    /// 更新人员ID
    pub update_user: Option<String>,
    /// 修改次数
    pub version: i32,
    /// 创建时间
    pub create_time: DateTime<Utc>,
    /// 更新时间
    pub update_time: DateTime<Utc>,
    /// 软删除标记
    pub is_deleted: bool,
    /// 标签集
    pub labels: Vec<String>,
}

impl Default for EntityBase {
    fn default() -> Self {
        Self {
            base: Base::default(),
            status: 1,
            create_user: None,
            update_user: None,
            version: 1,
            create_time: Utc::now(),
            update_time: Utc::now(),
            is_deleted: false,
            labels: Vec::new(),
        }
    }
}

#[allow(dead_code)]
impl EntityBase {
    /// 创建新实体
    pub fn new() -> Self {
        Self::default()
    }

    /// 获取所有属性名
    pub fn get_properties(&self) -> Vec<String> {
        let mut properties = vec![
            "id".to_string(),
            "name".to_string(),
            "status".to_string(),
            "createUser".to_string(),
            "updateUser".to_string(),
            "createTime".to_string(),
            "updateTime".to_string(),
            "version".to_string(),
            "isDeleted".to_string(),
            "labels".to_string(),
        ];
        
        for key in self.base.extensions.keys() {
            properties.push(key.clone());
        }
        
        properties
    }

    /// 通过属性名获取值
    pub fn get(&self, property: &str) -> Option<serde_json::Value> {
        match property {
            "id" => self.base.id.as_ref().map(|v| serde_json::Value::String(v.clone())),
            "name" => self.base.name.as_ref().map(|v| serde_json::Value::String(v.clone())),
            "status" => Some(serde_json::Value::Number(self.status.into())),
            "createUser" => self.create_user.as_ref().map(|v| serde_json::Value::String(v.clone())),
            "updateUser" => self.update_user.as_ref().map(|v| serde_json::Value::String(v.clone())),
            "createTime" => Some(serde_json::Value::String(self.create_time.to_rfc3339())),
            "updateTime" => Some(serde_json::Value::String(self.update_time.to_rfc3339())),
            "version" => Some(serde_json::Value::Number(self.version.into())),
            "isDeleted" => Some(serde_json::Value::Bool(self.is_deleted)),
            "labels" => Some(serde_json::Value::Array(
                self.labels
                    .iter()
                    .map(|label| serde_json::Value::String(label.clone()))
                    .collect(),
            )),
            _ => self.base.extensions.get(property).cloned(),
        }
    }

    /// 设置属性值
    pub fn set(&mut self, property: &str, value: serde_json::Value) -> Result<(), String> {
        match property {
            "id" => {
                if let serde_json::Value::String(v) = value {
                    self.base.id = Some(v);
                    Ok(())
                } else {
                    Err("id must be a string".to_string())
                }
            }
            "name" => {
                if let serde_json::Value::String(v) = value {
                    self.base.name = Some(v);
                    Ok(())
                } else {
                    Err("name must be a string".to_string())
                }
            }
            "status" => {
                if let serde_json::Value::Number(n) = value {
                    if let Some(v) = n.as_i64() {
                        self.status = v as i32;
                        Ok(())
                    } else {
                        Err("status must be an integer".to_string())
                    }
                } else {
                    Err("status must be a number".to_string())
                }
            }
            "createUser" => {
                if let serde_json::Value::String(v) = value {
                    self.create_user = Some(v);
                    Ok(())
                } else {
                    Err("createUser must be a string".to_string())
                }
            }
            "updateUser" => {
                if let serde_json::Value::String(v) = value {
                    self.update_user = Some(v);
                    Ok(())
                } else {
                    Err("updateUser must be a string".to_string())
                }
            }
            "createTime" => {
                if let serde_json::Value::String(v) = value {
                    match DateTime::parse_from_rfc3339(&v) {
                        Ok(dt) => {
                            self.create_time = dt.with_timezone(&Utc);
                            Ok(())
                        }
                        Err(_) => Err("createTime must be a valid RFC3339 datetime".to_string()),
                    }
                } else {
                    Err("createTime must be a string".to_string())
                }
            }
            "updateTime" => {
                if let serde_json::Value::String(v) = value {
                    match DateTime::parse_from_rfc3339(&v) {
                        Ok(dt) => {
                            self.update_time = dt.with_timezone(&Utc);
                            Ok(())
                        }
                        Err(_) => Err("updateTime must be a valid RFC3339 datetime".to_string()),
                    }
                } else {
                    Err("updateTime must be a string".to_string())
                }
            }
            "version" => {
                if let serde_json::Value::Number(n) = value {
                    if let Some(v) = n.as_i64() {
                        self.version = v as i32;
                        Ok(())
                    } else {
                        Err("version must be an integer".to_string())
                    }
                } else {
                    Err("version must be a number".to_string())
                }
            }
            "isDeleted" => {
                if let serde_json::Value::Bool(v) = value {
                    self.is_deleted = v;
                    Ok(())
                } else {
                    Err("isDeleted must be a boolean".to_string())
                }
            }
            "labels" => {
                if let serde_json::Value::Array(arr) = value {
                    let mut labels = Vec::new();
                    for item in arr {
                        if let serde_json::Value::String(label) = item {
                            labels.push(label);
                        } else {
                            return Err("labels must be an array of strings".to_string());
                        }
                    }
                    self.labels = labels;
                    Ok(())
                } else {
                    Err("labels must be an array".to_string())
                }
            }
            _ => {
                self.base.extensions.insert(property.to_string(), value);
                Ok(())
            }
        }
    }

    /// 浅克隆对象
    pub fn clone_entity(&self) -> Self {
        let mut clone = Self::new();
        for prop in self.get_properties() {
            if let Some(value) = self.get(&prop) {
                let _ = clone.set(&prop, value);
            }
        }
        clone
    }

    /// 填充实体ID
    pub fn fill_entity(&mut self) {
        if let Some(id_value) = self.base.extensions.get("id") {
            if let Some(id_str) = id_value.as_str() {
                self.base.id = Some(id_str.to_string());
                self.base.extensions.remove("id");
            }
        }
    }

    /// 批量填充实体
    pub fn fill_entities(entities: &mut [Self]) {
        for entity in entities {
            entity.fill_entity();
        }
    }
}

/// 从JSON数据创建实体
#[allow(dead_code)]
pub fn from_json_data(
    data: &serde_json::Value,
    user_id: &str,
) -> Result<(Vec<EntityBase>, bool), String> {
    let mut entities = Vec::new();
    let mut is_array = false;

    match data {
        serde_json::Value::Object(_obj) => {
            let entity = from_json_object(data, user_id)?;
            entities.push(entity);
        }
        serde_json::Value::Array(arr) => {
            for item in arr {
                if let serde_json::Value::Object(_) = item {
                    let entity = from_json_object(item, user_id)?;
                    entities.push(entity);
                }
            }
            is_array = true;
        }
        _ => return Err("Invalid JSON data type".to_string()),
    }

    Ok((entities, is_array))
}

/// 从JSON对象创建实体
fn from_json_object(data: &serde_json::Value, user_id: &str) -> Result<EntityBase, String> {
    let mut entity: EntityBase = serde_json::from_value(data.clone())
        .map_err(|e| format!("Failed to deserialize entity: {}", e))?;

    // 处理ID字段
    if let Some(id_value) = entity.base.extensions.get("id") {
        if let Some(id_str) = id_value.as_str() {
            entity.base.id = Some(id_str.to_string());
            entity.base.extensions.remove("id");
        }
    }

    // 设置用户信息
    if entity.create_user.is_none() {
        entity.create_user = Some(user_id.to_string());
    }
    entity.update_user = Some(user_id.to_string());
    entity.update_time = Utc::now();

    Ok(entity)
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;

    #[test]
    fn test_base_default() {
        let base = Base::default();
        assert_eq!(base.id, None);
        assert_eq!(base.name, None);
        assert!(base.extensions.is_empty());
    }

    #[test]
    fn test_base_serialization() {
        let mut base = Base::default();
        base.id = Some("test-id".to_string());
        base.name = Some("test-name".to_string());
        base.extensions.insert("custom_field".to_string(), json!("custom_value"));

        let serialized = serde_json::to_string(&base).unwrap();
        let deserialized: Base = serde_json::from_str(&serialized).unwrap();

        assert_eq!(deserialized.id, Some("test-id".to_string()));
        assert_eq!(deserialized.name, Some("test-name".to_string()));
        assert_eq!(deserialized.extensions.get("custom_field"), Some(&json!("custom_value")));
    }

    #[test]
    fn test_entity_creation() {
        let entity = EntityBase::new();
        assert_eq!(entity.status, 1);
        assert_eq!(entity.version, 1);
        assert!(!entity.is_deleted);
        assert!(entity.labels.is_empty());
        assert!(entity.create_user.is_none());
        assert!(entity.update_user.is_none());
    }

    #[test]
    fn test_entity_default() {
        let entity = EntityBase::default();
        assert_eq!(entity.status, 1);
        assert_eq!(entity.version, 1);
        assert!(!entity.is_deleted);
        assert!(entity.labels.is_empty());
        assert!(entity.create_user.is_none());
        assert!(entity.update_user.is_none());
    }

    #[test]
    fn test_get_properties() {
        let mut entity = EntityBase::new();
        entity.set("custom_field1", json!("value1")).unwrap();
        entity.set("custom_field2", json!("value2")).unwrap();

        let properties = entity.get_properties();
        assert!(properties.contains(&"id".to_string()));
        assert!(properties.contains(&"name".to_string()));
        assert!(properties.contains(&"status".to_string()));
        assert!(properties.contains(&"createUser".to_string()));
        assert!(properties.contains(&"updateUser".to_string()));
        assert!(properties.contains(&"createTime".to_string()));
        assert!(properties.contains(&"updateTime".to_string()));
        assert!(properties.contains(&"version".to_string()));
        assert!(properties.contains(&"isDeleted".to_string()));
        assert!(properties.contains(&"labels".to_string()));
        assert!(properties.contains(&"custom_field1".to_string()));
        assert!(properties.contains(&"custom_field2".to_string()));
    }

    #[test]
    fn test_get_set_properties() {
        let mut entity = EntityBase::new();
        
        // 设置内置属性
        assert!(entity.set("name", json!("test_name")).is_ok());
        assert!(entity.set("status", json!(2)).is_ok());
        
        // 设置扩展属性
        assert!(entity.set("custom_field", json!("custom_value")).is_ok());
        
        // 验证获取属性
        assert_eq!(entity.get("name"), Some(json!("test_name")));
        assert_eq!(entity.get("status"), Some(json!(2)));
        assert_eq!(entity.get("custom_field"), Some(json!("custom_value")));
    }

    #[test]
    fn test_set_method_error_handling() {
        let mut entity = EntityBase::new();

        // 测试错误类型处理
        assert!(entity.set("id", json!(123)).is_err()); // id必须是字符串
        assert!(entity.set("name", json!(123)).is_err()); // name必须是字符串
        assert!(entity.set("status", json!("invalid")).is_err()); // status必须是数字
        assert!(entity.set("createUser", json!(123)).is_err()); // createUser必须是字符串
        assert!(entity.set("updateUser", json!(123)).is_err()); // updateUser必须是字符串
        assert!(entity.set("createTime", json!(123)).is_err()); // createTime必须是字符串
        assert!(entity.set("updateTime", json!(123)).is_err()); // updateTime必须是字符串
        assert!(entity.set("version", json!("invalid")).is_err()); // version必须是数字
        assert!(entity.set("isDeleted", json!("invalid")).is_err()); // isDeleted必须是布尔值
        assert!(entity.set("labels", json!("invalid")).is_err()); // labels必须是数组
        
        // 测试无效的RFC3339时间格式
        assert!(entity.set("createTime", json!("invalid-date")).is_err());
        assert!(entity.set("updateTime", json!("invalid-date")).is_err());

        // 测试labels数组包含非字符串元素
        assert!(entity.set("labels", json!(["valid", 123])).is_err());
    }

    #[test]
    fn test_set_method_success_cases() {
        let mut entity = EntityBase::new();

        // 测试所有内置属性的正确设置
        assert!(entity.set("id", json!("test-id")).is_ok());
        assert!(entity.set("name", json!("test-name")).is_ok());
        assert!(entity.set("status", json!(5)).is_ok());
        assert!(entity.set("createUser", json!("user1")).is_ok());
        assert!(entity.set("updateUser", json!("user2")).is_ok());
        assert!(entity.set("version", json!(10)).is_ok());
        assert!(entity.set("isDeleted", json!(true)).is_ok());
        assert!(entity.set("labels", json!(["label1", "label2"])).is_ok());

        // 测试有效的时间格式
        let valid_time = "2023-01-01T00:00:00Z";
        assert!(entity.set("createTime", json!(valid_time)).is_ok());
        assert!(entity.set("updateTime", json!(valid_time)).is_ok());

        // 验证设置结果
        assert_eq!(entity.get("id"), Some(json!("test-id")));
        assert_eq!(entity.get("name"), Some(json!("test-name")));
        assert_eq!(entity.get("status"), Some(json!(5)));
        assert_eq!(entity.get("createUser"), Some(json!("user1")));
        assert_eq!(entity.get("updateUser"), Some(json!("user2")));
        assert_eq!(entity.get("version"), Some(json!(10)));
        assert_eq!(entity.get("isDeleted"), Some(json!(true)));
        assert_eq!(entity.get("labels"), Some(json!(["label1", "label2"])));
    }

    #[test]
    fn test_clone_entity() {
        let mut entity = EntityBase::new();
        entity.set("name", json!("original")).unwrap();
        entity.set("custom_field", json!("value")).unwrap();
        
        let clone = entity.clone_entity();
        
        assert_eq!(clone.get("name"), Some(json!("original")));
        assert_eq!(clone.get("custom_field"), Some(json!("value")));
    }

    #[test]
    fn test_fill_entity() {
        let mut entity = EntityBase::new();
        entity.base.extensions.insert("id".to_string(), json!("test-id"));
        
        entity.fill_entity();
        
        assert_eq!(entity.base.id, Some("test-id".to_string()));
        assert!(!entity.base.extensions.contains_key("id"));
    }

    #[test]
    fn test_fill_entities() {
        let mut entities = vec![
            EntityBase::new(),
            EntityBase::new(),
            EntityBase::new(),
        ];

        // 为每个实体设置扩展ID
        for (i, entity) in entities.iter_mut().enumerate() {
            entity.base.extensions.insert("id".to_string(), json!(format!("id-{}", i)));
        }

        EntityBase::fill_entities(&mut entities);

        for (i, entity) in entities.iter().enumerate() {
            assert_eq!(entity.base.id, Some(format!("id-{}", i)));
            assert!(!entity.base.extensions.contains_key("id"));
        }
    }

    #[test]
    fn test_from_json_object() {
        let json_data = json!({
            "_id": "json-id",
            "name": "json-name",
            "status": 3,
            "version": 1,
            "createUser": "json-user",
            "createTime": "2023-01-01T00:00:00Z",
            "updateTime": "2023-01-01T00:00:00Z",
            "isDeleted": false,
            "labels": [],
            "custom_field": "custom-value"
        });

        let entity = from_json_object(&json_data, "test-user").unwrap();

        assert_eq!(entity.base.id, Some("json-id".to_string()));
        assert_eq!(entity.base.name, Some("json-name".to_string()));
        assert_eq!(entity.status, 3);
        assert_eq!(entity.version, 1);
        assert_eq!(entity.create_user, Some("json-user".to_string()));
        assert_eq!(entity.update_user, Some("test-user".to_string()));
        assert_eq!(entity.is_deleted, false);
        assert_eq!(entity.labels, Vec::<String>::new());
        assert_eq!(entity.base.extensions.get("custom_field"), Some(&json!("custom-value")));
    }

    #[test]
    fn test_from_json_data_single_object() {
        let json_data = json!({
            "_id": "single-id",
            "name": "single-name",
            "status": 1,
            "version": 1,
            "createTime": "2023-01-01T00:00:00Z",
            "updateTime": "2023-01-01T00:00:00Z",
            "isDeleted": false,
            "labels": []
        });

        let (entities, is_array) = from_json_data(&json_data, "test-user").unwrap();

        assert_eq!(entities.len(), 1);
        assert!(!is_array);
        assert_eq!(entities[0].base.id, Some("single-id".to_string()));
        assert_eq!(entities[0].base.name, Some("single-name".to_string()));
        assert_eq!(entities[0].status, 1);
        assert_eq!(entities[0].version, 1);
        assert_eq!(entities[0].is_deleted, false);
        assert_eq!(entities[0].labels, Vec::<String>::new());
    }

    #[test]
    fn test_from_json_data_array() {
        let json_data = json!([
            {"_id": "id-1", "name": "name-1", "status": 1, "version": 1, "createTime": "2023-01-01T00:00:00Z", "updateTime": "2023-01-01T00:00:00Z", "isDeleted": false, "labels": []},
            {"_id": "id-2", "name": "name-2", "status": 1, "version": 1, "createTime": "2023-01-01T00:00:00Z", "updateTime": "2023-01-01T00:00:00Z", "isDeleted": false, "labels": []},
            {"_id": "id-3", "name": "name-3", "status": 1, "version": 1, "createTime": "2023-01-01T00:00:00Z", "updateTime": "2023-01-01T00:00:00Z", "isDeleted": false, "labels": []}
        ]);

        let (entities, is_array) = from_json_data(&json_data, "test-user").unwrap();

        assert_eq!(entities.len(), 3);
        assert!(is_array);
        for (i, entity) in entities.iter().enumerate() {
            assert_eq!(entity.base.id, Some(format!("id-{}", i + 1)));
            assert_eq!(entity.base.name, Some(format!("name-{}", i + 1)));
            assert_eq!(entity.status, 1);
            assert_eq!(entity.version, 1);
            assert_eq!(entity.is_deleted, false);
            assert_eq!(entity.labels, Vec::<String>::new());
        }
    }

    #[test]
    fn test_from_json_data_invalid_type() {
        let json_data = json!("invalid");
        let result = from_json_data(&json_data, "test-user");
        assert!(result.is_err());
    }

    #[test]
    fn test_entity_serialization_roundtrip() {
        let mut original = EntityBase::new();
        original.set("id", json!("serial-id")).unwrap();
        original.set("name", json!("serial-name")).unwrap();
        original.set("status", json!(7)).unwrap();
        original.set("custom_field", json!("serial-value")).unwrap();

        let serialized = serde_json::to_string(&original).unwrap();
        let deserialized: EntityBase = serde_json::from_str(&serialized).unwrap();

        assert_eq!(deserialized.base.id, original.base.id);
        assert_eq!(deserialized.base.name, original.base.name);
        assert_eq!(deserialized.status, original.status);
        assert_eq!(deserialized.base.extensions.get("custom_field"), 
                   original.base.extensions.get("custom_field"));
    }

    #[test]
    fn test_get_nonexistent_property() {
        let entity = EntityBase::new();
        assert_eq!(entity.get("nonexistent"), None);
    }

    #[test]
    fn test_set_extensions() {
        let mut entity = EntityBase::new();
        
        // 设置多个扩展属性
        assert!(entity.set("ext1", json!("value1")).is_ok());
        assert!(entity.set("ext2", json!(123)).is_ok());
        assert!(entity.set("ext3", json!(true)).is_ok());
        assert!(entity.set("ext4", json!(["a", "b"])).is_ok());
        assert!(entity.set("ext5", json!({"nested": "object"})).is_ok());

        // 验证扩展属性
        assert_eq!(entity.get("ext1"), Some(json!("value1")));
        assert_eq!(entity.get("ext2"), Some(json!(123)));
        assert_eq!(entity.get("ext3"), Some(json!(true)));
        assert_eq!(entity.get("ext4"), Some(json!(["a", "b"])));
        assert_eq!(entity.get("ext5"), Some(json!({"nested": "object"})));
    }

    #[test]
    fn test_labels_handling() {
        let mut entity = EntityBase::new();
        
        // 设置空标签数组
        assert!(entity.set("labels", json!([])).is_ok());
        assert_eq!(entity.labels.len(), 0);
        
        // 设置多个标签
        assert!(entity.set("labels", json!(["tag1", "tag2", "tag3"])).is_ok());
        assert_eq!(entity.labels, vec!["tag1", "tag2", "tag3"]);
        
        // 验证获取标签
        assert_eq!(entity.get("labels"), Some(json!(["tag1", "tag2", "tag3"])));
    }

    #[test]
    fn test_time_fields() {
        let mut entity = EntityBase::new();
        
        let test_time = "2023-12-31T23:59:59Z";
        assert!(entity.set("createTime", json!(test_time)).is_ok());
        assert!(entity.set("updateTime", json!(test_time)).is_ok());
        
        // 验证时间字段可以正确获取
        let create_time = entity.get("createTime").unwrap();
        let update_time = entity.get("updateTime").unwrap();
        
        // 时间格式可能包含时区信息，我们只验证包含相同的时间部分
        assert!(create_time.as_str().unwrap().contains("2023-12-31T23:59:59"));
        assert!(update_time.as_str().unwrap().contains("2023-12-31T23:59:59"));
    }
}